/**
 * Created by zhaoxk on 2017/2/14.
 */
import React from 'react';
import { connect } from 'dva';
import classnames from 'classnames';
import styles from './index.less';
import ToggleBtn from './toggleBtn';
import { carryFunc } from '../../utils';

const temp = {
    needConfig: true,
    size: null,
};
const renderDom = ({
    content,
    id,
    className,
    style,
    toggle = {},
    toggleSize,
}) => {
    if (content) {
        const toggleStyle = (type) => {
            const { topMove, sideMove, baseStyle } = toggle;
            const defaultMove = sideMove || `${toggleSize / (-2)}px`;
            switch (type) {
                case 'left': {
                    return {
                        ...baseStyle,
                        right: defaultMove,
                        marginTop: defaultMove,
                        top: topMove !== undefined ? topMove : '50%',
                    };
                }
                default: {
                    return {
                        ...baseStyle,
                        left: defaultMove,
                        marginTop: defaultMove,
                        top: topMove !== undefined ? topMove : '50%',
                    };
                }
            }
        };
        let toggleDom = null;
        if (toggle) {
            toggleDom = (
                <div
                    className={'toggle-wrap'}
                    style={toggleStyle(toggle.type)}
                >
                    {toggle.btn}
                </div>
            );
        }
        return (
            <div
                id={id}
                style={style}
                className={className}
            >
                {toggleDom}
                <div className="cont">{content}</div>
            </div>
        );
    }
    return null;
};

function FlexBox({ vertical, flex, dispatch, toggleBtn = {}, toggleSize = 32, ...args }) {
    /* 初始化时将实例的配置项覆盖store */
    const {
        config: c,
        headerHeight,
        footerHeight,
    } = args;
    if (temp.needConfig && c) {
        dispatch({
            type: 'flex/setting',
            payload: { config: c },
        });
        temp.needConfig = false;
    }

    /*
     * 主内容区滚动回调，
     * 通用参数distance 滚动距顶部距离，类型Int，单位px
     * onScrollTop, 到顶
     * onScrollBottom, 到底
     * onScrollDown, 向下滚动
     * onScrollUp, 向上滚动
     * onScroll, 滚动中, 第二个参数是滚动方向
     * */
    const { onScrollTop, onScrollBottom, onScrollDown, onScrollUp, onScroll } = args;
    const { up, down, scroll, top, bottom, distance } = flex.scroll;
    if (top) {
        carryFunc(onScrollTop, distance);
    }
    if (bottom) {
        carryFunc(onScrollBottom, distance);
    }
    if (up) {
        carryFunc(onScrollUp, distance);
    }
    if (down) {
        carryFunc(onScrollDown, distance);
    }
    if (scroll) {
        carryFunc(onScroll, distance, (up ? 'up' : 'down'));
    }

    /* 开始渲染DOM
     * 将DOM组件、可见、屏幕尺寸类型属性拿到
     * */
    const { header, footer, left, right, children } = args;
    const { size, visible } = flex;
    const { header: vh, footer: vf, left: vl, right: vr } = visible || {};

    /* 执行size变更回调 onRespond*/
    if (temp.size === null) {
        temp.size = size || null;
    } else if (size && size !== temp.size) {
        const { onRespond } = args;
        carryFunc(onRespond, size);
        temp.size = size;
    }

    /* 根据可见状态设置DOM组件的classnames */
    const pressHandler = (dir) => {
        const left = {
            left: !vl,
            right: vr,
        };
        const right = {
            left: vl,
            right: !vr,
        };
        dispatch({
            type: 'flex/toggleSideBar',
            payload: dir === 'left' ? left : right,
        });
    };
    const hS = classnames({
        vertical: true,
        vHide: !vh,
    });
    const fS = classnames({
        vertical: true,
        vHide: !vf,
    });
    const lS = classnames({
        horizontal: true,
        hHide: !vl,
    });
    const rS = classnames({
        horizontal: true,
        hHide: !vr,
    });
    const { btn, topMove, sideMove, baseStyle } = toggleBtn;
    const MyToggleBtn = btn || ToggleBtn;
    const leftBar = renderDom({
        content: left,
        id: '_leftBar',
        className: lS,
        style: {},
        toggle: {
            type: 'left',
            btn: (
                <MyToggleBtn
                    type={!vl}
                    size={toggleSize}
                    onPress={pressHandler.bind(null, 'left')}
                />
            ),
            baseStyle,
            topMove,
            sideMove,
        },
        toggleSize
    });
    const rightBar = renderDom({
        content: right,
        id: '_rightBar',
        className: rS,
        style: {},
        toggle: {
            type: 'right',
            btn: (
                <MyToggleBtn
                    type={!vl}
                    size={toggleSize}
                    onPress={pressHandler.bind(null, 'left')}
                />
            ),
            baseStyle,
            topMove,
            sideMove,
        },
        toggleSize
    });
    const topBar = renderDom({
        content: header,
        id: '_header',
        className: hS,
        style: {
            height: vh ? (headerHeight || '56px') : 0,
        }
    });
    const bottomBar = renderDom({
        content: footer,
        id: '_footer',
        className: fS,
        style: {
            height: vf ? (footerHeight || '22px') : 0,
        },
    });

    const content = (
        <div
            id="_content"
            className={styles.content}
        >
            <div id="_contWrap" className={styles.contWrap}>
                {children}
            </div>
        </div>
    );

    const { style: s = {} } = args;
    const style = {
        ...s,
        width: '100%'
    };
    if (!vertical) {
        return (
            <div id="flexWrap" style={style} className={styles.flexWrap}>
                <div className={styles.horizontalMain}>
                    {leftBar}
                    <div className={styles.verticalMain}>
                        {topBar}
                        {content}
                        {bottomBar}
                    </div>
                    {rightBar}
                </div>
            </div>
        );
    }
    return (
        <div style={style}>
            <div className={styles.verticalMain}>
                {topBar}
                <div className={styles.horizontalMain}>
                    {leftBar}
                    {content}
                    {rightBar}
                </div>
                {bottomBar}
            </div>
        </div>
    );
}

function mapStateToProps({ flex }) {
    return { flex };
}

export default connect(mapStateToProps)(FlexBox);
